package yapl.symbolChecker;

import java.util.Hashtable;
import java.util.Set;
import java.util.Stack;

import yapl.interfaces.SymbolTableInterface;

public class SymbolTable  implements SymbolTableInterface {
	
	public Stack<Hashtable<String,Symbol>> scopes=new Stack<Hashtable<String,Symbol>>();
	
	public SymbolTable() {
		Hashtable<String,Symbol> temp=new Hashtable<String,Symbol>();
		temp.put("writeint",new Symbol(2));
		temp.put("writebool", new Symbol(2));
		temp.put("writeln", new Symbol(2));
		temp.put("readint", new Symbol(2));
		scopes.push(temp);
	}

	@Override
	public void openScope() {
		Main.shouldOpenScope=true;
		Hashtable<String,Symbol> temp=new Hashtable<String,Symbol>();
		scopes.push(temp);
		
	}

	@Override
	public void closeScope() {
		scopes.pop();
		
	}	
	
	public void addSymbol(String token, int kind) throws SymbolException{
		if(scopes.peek().containsKey(token)) {
			Main.error(10);
		}
		scopes.peek().put(token,new Symbol(kind));
	}
	
	public void addSymbol(Symbol s) throws SymbolException{
		if(scopes.peek().containsKey(s.getKind())) {
			Main.error(10);
		}
		scopes.peek().put(s.getName(),s);
	}
	
	public String kindToString(int kind) {
		if (kind==1) return "program";
		else if(kind==2) return "procedure";
		else if(kind==3) return "variable";
		else if(kind==4) return "constant";
		else if(kind==5) return "typename";
		else if(kind==6) return "field";
		else{ return "parameter";}	
	}	

	@Override
	public String lookup(String name) /*throws ParseException*/ {
		
		for (int i=scopes.size()-1;i>=0;i--) {
			boolean temp = scopes.get(i).containsKey(name);
			if(temp==true) return kindToString(scopes.get(i).get(name).getKind());
		}
		return "not found";
	}
	
	public Symbol getSymbol(String name) {
		Symbol symbol = null;
		for (int i=scopes.size() - 1; i >= 0; i--) {			
			if (scopes.get(i).get(name).equals(name)) {
				symbol = scopes.get(i).get(name);
			}			
		}
		return symbol;		
	}
	
	public void printSymbolTable(){
		for(Hashtable<String,Symbol> i : scopes) {
			Set<String> temp = i.keySet();
			System.out.println("Beginning of new scope");
			for(String j: temp){
				System.out.println(j);
				System.out.println(i.get(j));
			}
		}
	}
	
	public boolean isInSymbolTable(String token){
		boolean found=false;

		for (int i=0;i<scopes.size();i++) {
			if(scopes.get(i).containsKey(token)) found=true;
		}
		return found;
	}

	@Override
	public void setParentSymbol(Symbol sym) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Symbol getNearestParentSymbol(int kind) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setDebug(boolean on) {
		// TODO Auto-generated method stub
		
	}	

}